<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>使用slot分发内容__作用域插槽</title>
</head>
<body>

<div id="app">
    <children-component>
        <template scope="props">
            <p>来自父组件的内容</p>
            <p>{{ props.msg }}</p>
        </template>
    </children-component>
</div>

<hr>

<div id="app1">
    <my-list :books="books">
        <!-- 作用域插槽也可以是具名slot -->
        <template slot="book" scope="props">
            <li>{{ props.bookName }}</li>
        </template>
    </my-list>
</div>

<hr>


<div id="app2">
    <ul>
        <li v-for="book in books">{{ book.name }}</li>
    </ul>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    /**
     *
     * 作用域插槽是一种特殊的slot，使用一个可以复用的模板替换已渲染元素。
     *
     * **/

    Vue.component("children-component", {
        template: "<div class='container'><slot msg='来自子组件的内容'></slot></div>"
    });

    var app = new Vue({
        el: "#app",
    });

    /**
     * 观察子组件的模板，在<slot>元素上有一个类似props传递数据给组件的写法msg="xxx",将数据传到了插槽。
     * 父组件中使用了<template>元素，且拥有一个scope="props"的特性，这里的props只是一个临时变量，就像v-for="item in items"里面的item一样。
     * 在template里可以通过临时变量props访问来自子组件插槽的数据msg。
     * **/


    /**
     * 作用域插槽更具代表性的用例是列表组件，允许组件自定义应该如何渲染列表的每一项。
     * **/


    /**
     * 子组件my-list接收一个来自父级的prop数组books，并且将它在name为book的slot上使用v-for指令循环，同时暴露一个变量bookName。
     *
     * 作用域插槽的使用场景就是既可以复用子组件的slot，又可以使slot内容不一致。
     * **/
    Vue.component("my-list", {
        props: {
            books: {
                type: Array,
                default: function () {
                    return [];
                }
            }
        },
        template: "<ul><slot name='book' v-for='book in books' :book-name='book.name'>这里是slot的默认内容</slot></ul>"
    });

    var app1 = new Vue({
        el: "#app1",
        data: {
            books: [{
                name: "Python"
            }, {
                name: "JavaScript"
            }, {
                name: "Go"
            }]
        }
    });


    var app2 = new Vue({
        el: "#app2",
        data: {
            books: [{
                name: "Python"
            }, {
                name: "JavaScript"
            }, {
                name: "Go"
            }]
        }
    })


</script>
</body>
</html>
